Na het lezen van Hidden Features and Dark Corners of C ++ / STL op comp.lang.c ++. Gemodereerd, was ik volledig verrast dat het volgende fragment compileerde en werkte in zowel Visual Studio 2008 als G ++ 4.4. Hier is de code: # includeint belangrijkste () { int x = 10; while (x -> 0) // x gaat naar 0 { printf ("% d", x); } } Uitgang: 9 8 7 6 5 4 3 2 1 0 Ik neem aan dat dit C is, omdat het ook in GCC werkt. Waar wordt dit gedefinieerd in de norm en waar komt het vandaan?
2020-12-07 21:23:31
-> is geen operator. Het zijn in feite twee afzonderlijke operatoren, - en>. De voorwaardelijke code verlaagt x, terwijl de oorspronkelijke (niet verlaagde) waarde van x wordt geretourneerd, en vergelijkt vervolgens de oorspronkelijke waarde met 0 met de operator>. Voor een beter begrip zou de verklaring als volgt kunnen worden geschreven: terwijl ((x--)> 0) | Of voor iets heel anders ... x schuift naar 0. terwijl (x - \ \ \ \ > 0) printf ("% d", x); Niet zo wiskundig, maar ... elk plaatje zegt meer dan duizend woorden ... | Dat is een erg gecompliceerde operator, dus zelfs ISO / IEC JTC1 (Joint Technical Committee 1) plaatste zijn beschrijving in twee verschillende delen van de C ++ -standaard. Een grapje terzijde, het zijn twee verschillende operatoren: - en> beschreven in respectievelijk §5.2.6 / 2 en §5.9 van de C ++ 03-standaard. | Het is gelijk aan terwijl (x--> 0) x-- (post decrement) is gelijk aan x = x-1, dus de code transformeert naar: while (x> 0) { x = x-1; // logica } X--; // De postverlaging gedaan wanneer x <= 0 | x kan nog sneller naar nul gaan in de tegenovergestelde richting: int x = 10; terwijl (0 <---- x) { printf ("% d", x); } 8 6 4 2 U kunt de snelheid regelen met een pijl! int x = 100; terwijl (0 <-------------------- x) { printf ("% d", x); } 90 80 70 60 50 40 30 20 10 ;) | Haar # includeint main (void) { int x = 10; while (x--> 0) {// x gaat naar 0 printf ("% d", x); } retourneer 0; } Alleen al de ruimte laat de dingen er grappig uitzien, - verkleint en> vergelijkt. | Het gebruik van -> heeft historische relevantie. Decrementeren was (en is in sommige gevallen nog steeds) sneller dan verhogen op de x86-architectuur. Het gebruik van -> suggereert dat x naar 0 gaat, en spreekt mensen met een wiskundige achtergrond aan. | terwijl (x--> 0) is hoe dat wordt geparseerd. | Helemaal nerd, maar ik zal dit gebruiken: #define as; while int main (int argc, char * argv []) { int n = atoi (argv [1]); do printf ("n is% d \ n", n) als (n -> 0); retourneer 0; } | Een boek dat ik las (ik herinner me niet goed welk boek) zei: Compilers proberen uitdrukkingen te ontleden tot het grootste teken door de linker-rechterregel te gebruiken. In dit geval de uitdrukking: x -> 0 Parseert naar grootste tokens: token 1: x token 2: - token 3:> token 4: 0 concluderen: x--> 0 Dezelfde regel is van toepassing op deze uitdrukking: een ----- b Na ontleden: token 1: a token 2: - token 3: - token 4: - token 5: b concluderen: (a -) - - b Ik hoop dat dit helpt om de gecompliceerde uitdrukking ^^ te begrijpen | Dit is precies hetzelfde als terwijl (x--) { printf ("% d", x); } voor niet-negatieve getallen | Hoe dan ook, we hebben nu een "gaat naar" -operator. "->" is gemakkelijk te onthouden als een richting, en "terwijl x naar nul gaat" is een rechte betekenis. Bovendien is het op sommige platforms iets efficiënter dan "for (x = 10; x> 0; x -)". | Deze code vergelijkt eerst x en 0 en verlaagt vervolgens x. (Ook gezegd in het eerste antwoord: je verlaagt x achteraf en vergelijkt vervolgens x en 0 met de operator>.) Zie de uitvoer van deze code: 9 8 7 6 5 4 3 2 1 0 We vergelijken nu eerst en verlagen vervolgens door 0 in de uitvoer te zien. Als we eerst willen verlagen en dan vergelijken, gebruik dan deze code: # include int main (leegte) { int x = 10; while (--x> 0) // x gaat naar 0 { printf ("% d", x); } retourneer 0; } Die output is: 9 8 7 6 5 4 3 2 1 | Mijn compiler zal 9876543210 afdrukken als ik deze code uitvoer. # include int belangrijkste () { int x = 10; while (x -> 0) // x gaat naar 0 { std :: cout << x; } } Zoals verwacht. De while (x--> 0) betekent eigenlijk while (x> 0). De x-- post verlaagt x. terwijl (x> 0) { X--; std :: cout << x; } is een andere manier om hetzelfde te schrijven. Het is echter leuk dat het origineel eruitziet als "terwijl x naar 0 gaat". | Er ontbreekt een spatie tussen - en>. x wordt achteraf verlaagd, dat wil zeggen verlaagd na controle van de voorwaarde x> 0?. | - is de operator voor verlagen en> is de operator voor groter dan. De twee operatoren worden toegepast als een enkele, zoals ->. | Het is een combinatie van twee operators. Ten eerste - is om de waarde te verlagen en> is om te controleren of de waarde groter is dan de rechter operand. # include int belangrijkste () { int x = 10; terwijl (x--> 0) printf ("% d", x); retourneer 0; } De output zal zijn: 9 8 7 6 5 4 3 2 1 0 | In feite is x post-decrementerend en wordt met die voorwaarde gecontroleerd. Het is niet ->, het is (x--)> 0 Opmerking: de waarde van x wordt gewijzigd nadat de voorwaarde is gecontroleerd, omdat deze post-decrementeert. Enkele soortgelijke gevallen kunnen ook voorkomen, bijvoorbeeld: -> x -> 0 ++> x ++> 0 -> = x -> = 0 ++> = x ++> = 0 | C en C ++ volgen de regel "maximum munch". Op dezelfde manier als a --- b wordt vertaald naar (a--) - b, wordt in jouw geval x -> 0 vertaald naar (x -)> 0. Wat de regel in wezen zegt, is dat als je van links naar rechts gaat, uitdrukkingen worden gevormd door het maximum aantal tekens te nemen dat een geldige uitdrukking zal vormen. | Waarom alle complicaties? Het simpele antwoord op de oorspronkelijke vraag is gewoon: # include int belangrijkste () { int x = 10; terwijl (x>0) { printf ("% d", x); x = x-1; } } Het doet hetzelfde. Ik zeg niet dat je het op deze manier zou moeten doen, maar het doet hetzelfde en zou de vraag in één post hebben beantwoord. De x-- is slechts een afkorting voor het bovenstaande, en> is gewoon een normale groter-dan-operator. Geen groot mysterie! Er zijn tegenwoordig te veel mensen die simpele dingen ingewikkeld maken;) | Op de conventionele manier zouden we een voorwaarde definiëren in de while-lus tussen haakjes () en een afsluitende voorwaarde tussen de accolades {}, maar -> definieert beide tegelijk. Bijvoorbeeld: int abc (ongeldig) { int a = 5 while ((a--)> 0) // Verlaging en vergelijking beide tegelijk { // Code } } Dit verlaagt a en voert de lus uit terwijl a groter is dan 0. Conventioneel zou het zijn als: int abc (ongeldig) { int a = 5; terwijl (a> 0) { een--; // Code } een--; } Op beide manieren doen we hetzelfde en bereiken we dezelfde doelen. | (x -> 0) betekent (x--> 0). U kunt (x ->) Uitgang gebruiken: 9 8 7 6 5 4 3 2 1 0 U kunt (- x> 0) Het is gemiddeld (--x> 0) Uitvoer: 9 8 7 6 5 4 3 2 1 Je kunt gebruiken (- \ \ x> 0) Uitgang: 9 8 7 6 5 4 3 2 1 Je kunt gebruiken (\ \ x -> 0) Uitgang: 9 8 7 6 5 4 3 2 1 0 Je kunt gebruiken (\ \ x -> 0 \ \ ) Uitgang: 9 8 7 6 5 4 3 2 1 0 U kunt ook gebruiken ( X -> ) Uitgang: 9 8 7 6 5 4 3 2 1 0 Evenzo kunt u veel methoden proberen om deze opdracht met succes uit te voeren. | Hier - is de unaire postverlagingsoperator. while (x--> 0) // x gaat naar 0 { printf ("% d", x); } In het begin zal de toestand evalueren als (x> 0) // 10> 0 Omdat de voorwaarde waar is, gaat deze de lus in met een verlaagde waarde x-- // x = 9 Daarom is de eerste afgedrukte waarde 9 Enzovoorts. In de laatste lus x = 1, dus de voorwaarde is waar. Volgens de unaire operator veranderde de waarde in x = 0 op het moment van afdrukken. Nu is x = 0, wat de voorwaarde (x> 0) evalueert als onwaar en de while-lus wordt afgesloten. | Dit -> is helemaal geen operator. We hebben een operator zoals ->, maar niet zoals ->. Het is gewoon een verkeerde interpretatie van while (x--> 0), wat simpelweg betekent dat x de post-verlagingsoperator heeft en deze lus zal lopen totdat deze groter is dan nul. Een andere eenvoudige manier om deze code te schrijven is while (x--). De while-lus stopt wanneer deze een false-conditie krijgt en hier is er maar één geval, namelijk 0. Dus hij stopt wanneer de x-waarde wordt verlaagd naar nul. | Zeer actieve vraag. Verdien 10 reputatie om deze vraag te beantwoorden. De reputatievereiste helpt deze vraag te beschermen tegen spam en niet-beantwoording. Niet het antwoord waar je naar zoekt? Blader door andere vragen met de tag c ++ c operators code-opmaak standaarden-compliance of stel uw eigen vraag.